/*
 * Rule.cpp
 *
 *  Created on: Apr 30, 2012
 *      Author: kobe
 */

#include "Rule.h"

#include "RActionAndL1.h"
#include "RActionAndL2.h"
#include "RAndL.h"
#include "RAndR.h"
#include "RApp.h"
#include "RBlackDiamondL.h"
#include "RBlackDiamondR.h"
#include "RDist.h"
#include "RDyDist.h"
#include "RDyL.h"
#include "RDyR.h"
#include "RMonoidL.h"
#include "RMonoidR.h"
#include "ROrL.h"
#include "ROrR1.h"
#include "ROrR2.h"
#include "RPrApp.h"
#include "RReArr.h"
#include "RReArrRev.h"
#include "RSquareL.h"
#include "RSquareR.h"
#include "RUpdateR.h"
#include "RUpdateL.h"

Rule::Rule() {
	// TODO Auto-generated constructor stub

}

Rule::~Rule() {
	// TODO Auto-generated destructor stub
}

std::vector<Sequent*> Rule::run(Sequent* s) {
	std::vector<Sequent*> l;
	return l;
}

std::string Rule::toString() {
	std::string s;
	return s;
}

bool Rule::isVariousRule() {
	return false;
}

Context* Rule::searchContextInContext(Context* context, Context* orig) {
	if (orig->compare(context)) {
		return orig;
	} else {
		for (size_t i = 0; i < orig->getItemList().size(); i++) {
			if (orig->getItemList().at(i)->compare(context)) {
				return orig->getItemList().at(i);
			}
		}

		for (size_t j = 0; j < orig->getActionList().size(); j++) {
			if (orig->getActionList().at(j)->compare(context)) {
				return orig->getActionList().at(j);
			}
		}

		return NULL;
	}
}

Context* Rule::searchActionOperatorInContext(Context* context,
		ModalLogic type) {
	if (context->getType() == CONTEXT_ACTION) {
		if (context->getProposition()->getPropName() == type && context->getProposition()->isAction()) {
			return context;
		}
	} else {
		Context* result = NULL;
		if (context->getType() == ACTIONCONTEXT || context->getType() == ACTIONANNOTATEDCONTEXT) {
			if (context->getActionList().size() > 0) {
				for (size_t i = 0; i < context->getActionList().size(); i++) {
					result = searchActionOperatorInContext(
							context->getActionList()[i], type);
					if (result != NULL) {
						return result;
					}
				}
			}
		}
		for (size_t i = 0; i < context->getItemList().size(); i++) {
			result = searchActionOperatorInContext(context->getItemList()[i],
					type);
			if (result != NULL) {
				return result;
			}
		}
	}
	return NULL;
}

Context* Rule::searchOperatorInContext(Context* context, ModalLogic type) {
	if (context->getType() == CONTEXT_PROPOSITION) {
		if (context->getProposition()->getPropName() == type) {
			return context;
		}
	} else {
		Context* result = NULL;
		for (size_t i = 0; i < context->getItemList().size(); i++) {
			result = searchOperatorInContext(context->getItemList()[i], type);
			if (result == NULL) {
				continue;
			} else {
				return result;
			}
		}
	}
	return NULL;
}

std::string Rule::toLatex() {
	std::string s("Base Rule");
	return s;
}

std::vector<Rule*> registerAllRulesEpistemic() {
	R_ActionAndL1 *ral1 = new R_ActionAndL1;
		R_ActionAndL2 *ral2 = new R_ActionAndL2;
		R_AndL *ral = new R_AndL;
		R_AndR *rar = new R_AndR;
		R_BlackDiamondL *rbdl = new R_BlackDiamondL;
		R_BlackDiamondR *rbdr = new R_BlackDiamondR;
		R_Dist *rd = new R_Dist;
		R_DyDist *rdd = new R_DyDist;
		R_DyL *rdl = new R_DyL;
		R_DyR *rdr = new R_DyR;
		R_MonoidR *rmr = new R_MonoidR;
		R_MonoidL *rml = new R_MonoidL;
		R_OrL *rol = new R_OrL;
		R_OrR1 *ror1 = new R_OrR1;
		R_OrR2 *ror2 = new R_OrR2;
		R_ReArr *rra = new R_ReArr;
		R_ReArr_Rev *rrar = new R_ReArr_Rev;
		R_SquareL *rsl = new R_SquareL;
		R_SquareR *rsr = new R_SquareR;
		R_UpdateL *rul = new R_UpdateL;
		R_UpdateR *rur = new R_UpdateR;

		std::vector<Rule*> list;
		list.push_back(rul);
		list.push_back(rur);
		list.push_back(rdl);
		list.push_back(rdr);
		list.push_back(ror1);
		list.push_back(ror2);
		list.push_back(rbdl);
		list.push_back(rbdr);
		list.push_back(rsr);
		list.push_back(ral);
		list.push_back(ral1);
		list.push_back(ral2);
		list.push_back(rar);
		list.push_back(rol);
		list.push_back(rmr);
		list.push_back(rml);
		list.push_back(rsl);
		list.push_back(rd);
		list.push_back(rdd);
		list.push_back(rra);
		list.push_back(rrar);

		return list;
}

std::vector<Rule*> registerAllRules() {
	R_ActionAndL1 *ral1 = new R_ActionAndL1;
	R_ActionAndL2 *ral2 = new R_ActionAndL2;
	R_AndL *ral = new R_AndL;
	R_AndR *rar = new R_AndR;
	R_BlackDiamondL *rbdl = new R_BlackDiamondL;
	R_BlackDiamondR *rbdr = new R_BlackDiamondR;
	R_Dist *rd = new R_Dist;
	R_DyDist *rdd = new R_DyDist;
	R_DyL *rdl = new R_DyL;
	R_DyR *rdr = new R_DyR;
	R_MonoidR *rmr = new R_MonoidR;
	R_MonoidL *rml = new R_MonoidL;
	R_OrL *rol = new R_OrL;
	R_OrR1 *ror1 = new R_OrR1;
	R_OrR2 *ror2 = new R_OrR2;
	R_ReArr *rra = new R_ReArr;
	R_ReArr_Rev *rrar = new R_ReArr_Rev;
	R_SquareL *rsl = new R_SquareL;
	R_SquareR *rsr = new R_SquareR;
	R_UpdateL *rul = new R_UpdateL;
	R_UpdateR *rur = new R_UpdateR;

	std::vector<Rule*> list;
	list.push_back(rul);
	list.push_back(rur);
	list.push_back(rdl);
	list.push_back(rdr);
	list.push_back(ror1);
	list.push_back(ror2);
	list.push_back(rbdl);
	list.push_back(rbdr);
	list.push_back(rsr);
	list.push_back(ral);
	list.push_back(ral1);
	list.push_back(ral2);
	list.push_back(rar);
	list.push_back(rol);
	list.push_back(rmr);
	list.push_back(rml);
	list.push_back(rra);
	list.push_back(rrar);
	list.push_back(rsl);
	list.push_back(rd);
	list.push_back(rdd);

	return list;
}

bool Rule::isLoopRule() {
	return false;
}

void Rule::popLastSequent() {

}

RuleType Rule::getRuleType() {
	return OTHER;
}
